home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / admin / news / newswarn < prev    next >
Encoding:
Korn shell script  |  1997-08-26  |  6.7 KB  |  220 lines

  1. #!/bin/ksh
  2. # @(#) newswarn.ksh 1.1 94/11/19
  3. # 94/09/18 john h. dubois iii (john@armory.com)
  4. # 94/11/06 Removed c option; now no g opt means check-only.
  5. # 94/11/19 Explicitely state if noone is using the news server.
  6.  
  7. # Output of command 'sockinfo -st':
  8. # tcp        0      0  192.122.209.42.4724    192.122.209.39.119     CLOSE_WAIT
  9. #    PID 24777: trn
  10. # user bdp on tty /dev/ttyp50
  11.  
  12. # Usage: FindPortUsers <ip-address> <port-number>
  13. # Output is lines of the form:
  14. # <user> <tty>
  15. # Line are also written to stderr with the form:
  16. # User <user> on tty <tty> is running <ps-name> (pid <process-id>).
  17.  
  18. # Output of sockinfo has the format:
  19. # line describing a socket used by a process
  20. # ....
  21. # name and pid of the process using the above sockets
  22. # user and controlling tty for the above process
  23. # Example:
  24. #Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
  25. #tcp        0      0  192.122.209.42.4669    129.24.12.18.7326      ESTABLISHED
  26. #   PID 3362: icb 
  27. #user turtle on tty /dev/ttyp25
  28. #tcp        0      0  192.122.209.42.80      192.122.209.42.4667    TIME_WAIT
  29. #tcp        0      0  192.122.209.42.4666    198.7.0.2.25           TIME_WAIT
  30. #tcp        0   1219  192.122.209.42.20      141.222.1.3.1081       FIN_WAIT_1
  31. #tcp        0      0  192.122.209.42.21      141.222.1.3.1080       ESTABLISHED
  32. #   PID 3061: Mosaic 
  33. #user zap on tty /dev/ttyp21
  34. #tcp        0      0  127.0.0.1.6001         127.0.0.1.4592         ESTABLISHED
  35. # Returns 1 if no users are using the specified ip-address/port-number,
  36. # 0 if any are.
  37. function FindPortUsers {
  38.     sockinfo -st | gawk -v ip="$1" -v Port="$2" '
  39.     BEGIN {
  40.     # Escape dots in IP address so that it can be used as a regex,
  41.     # so that a port number of .* will have the right effect
  42.     gsub(/\./,"\\.",ip)
  43.     FoundUser = 0
  44.     }
  45.  
  46.     # Find processes connected to a particular port on the news server.
  47.     $1 == "tcp" {
  48.         if ($5 ~ "^" ip "\\." Port "$")
  49.         PortUser = 1
  50.     next
  51.     }
  52.     $1 == "PID" {
  53.     pid = $2
  54.     gsub(":","",pid)
  55.     procname = $3
  56.     next
  57.     }
  58.     $1 == "user" {
  59.     tty = substr($5,6)
  60.     if (pid == "") {
  61.         print "User line found before process line... ignoring!" \
  62.         > "/dev/stderr"
  63.     }
  64.     else if (PortUser && tty != "socksys") {    # Just ignore socksys
  65.         user = $2
  66.         printf "User %s on %s is running %s (pid %d).\n",
  67.         user,tty,procname,pid > "/dev/stderr"
  68.         if (pid !~ "^[0-9]+$")
  69.         print "Strange pid... ignoring!" > "/dev/stderr"
  70.         else if (user !~ "^[a-z][a-z0-9]+$")
  71.         print "Strange user name... ignoring!" > "/dev/stderr"
  72.         else if (tty !~ "^tty")
  73.         print "Strange tty name... ignoring!" > "/dev/stderr"
  74.         else {
  75.         printf "%s %s\n",user,tty
  76.         FoundUser = 1
  77.         }
  78.         PortUser = 0
  79.     }
  80.     pid = ""
  81.     }
  82.     END {
  83.     exit !FoundUser
  84.     }
  85.     '
  86. }
  87.  
  88. ln_name=${0##*/}
  89. Usage="Usage: $ln_name [-h] [-g<grace-period>] [-s<news-server>] [-p<port>]"
  90. ServerFiles="/usr/lib/news/server /usr/lib/news/rn/server"
  91. typeset -i Grace=-1
  92. Port=119
  93.  
  94. while getopts :hcg:s:p: opt; do
  95.     case $opt in
  96.     h)
  97.     echo \
  98. "$ln_name: Warn users of impending shutdown of the news server.
  99. $ln_name finds all users who are using the system's news server, reports on
  100. them, and optionally warns them that the news server is about to be shut down. 
  101. Users are repeatedly warned at one minute intervals until the grace period has
  102. expired.  Before each warning, the users still using the news server are
  103. reported on, so that it can easily be determined when all users have finished.
  104. A final warning of immediate shutdown is issued at 0 minutes; a grace period of
  105. 0 can be used to give only this warning.  No action is taken when the grace
  106. period expires (the news server must be shut down manually).
  107. $ln_name determines who is using the news server by searching for processes
  108. that have connections to the NNTP port on the news server used by the local
  109. system.  To determine the name of the news server used by the local system,
  110. $ln_name first checks the environment variable NNTPSERVER, and then checks in
  111. order the files /usr/lib/news/server and /usr/lib/news/rn/server.  The first
  112. value found is used.
  113. $Usage
  114. Options:
  115. -g<grace-period>: Set the grace period to <grace-period> minutes, and warn
  116.     users.  Without this option, $ln_name will report once on who is using the
  117.     news server, but will not issue any warnings.
  118. -h: Print this help.
  119. -p<port>: Check for connections to the news server on the given port, instead
  120.     of the default port of $Port (NNTP service).  <port> can be a regular
  121.     expression in the style of egrep(C).  If a port number of 0 is given, 
  122.     it is translated to \".*\", so users with processes connected to the news
  123.     server on any port are warned.  <port> must be a decimal integer.
  124. -s<news-server>: Set news server by name or IP number."
  125.     exit 0
  126.     ;;
  127.     p)  
  128.     Port=$OPTARG
  129.     ;;
  130.     s)  NNTPSERVER=$OPTARG;;
  131.     g)
  132.     if [[ "$OPTARG" != [1-9]*([0-9]) ]]; then
  133.         print -u2 "Bad number of minutes: $OPTARG.  Aborting."
  134.         exit 1
  135.     fi
  136.     Grace=$OPTARG
  137.     ;;
  138.     +?)
  139.     print -u2 "$ln_name: options should not be preceded by a '+'."
  140.     exit 1
  141.     ;;
  142.     ?) 
  143.     print -u2 "$ln_name: $OPTARG: bad option.  Use -h for help."
  144.     exit 1
  145.     ;;
  146.     esac
  147. done
  148.  
  149. # remove args that were options
  150. let OPTIND=OPTIND-1
  151. shift $OPTIND
  152.  
  153. if [ $# -gt 0 ]; then
  154.     print -u2 "$Usage\nUse -h for help."
  155.     exit
  156. fi
  157.  
  158. if [ -z "$NNTPSERVER" ]; then
  159.     for file in $ServerFiles; do
  160.     read NNTPSERVER 2>/dev/null < $file && break
  161.     done
  162. fi
  163.  
  164. if [ -z "$NNTPSERVER" ]; then
  165.     print -u2 "Could not determine news server name."
  166.     exit 1
  167. fi
  168.  
  169. # Get the ip address of the news server so that sockinfo doesn't have to
  170. # look up the names of all ip connections
  171. if [[ "$NNTPSERVER" = +([0-9])+(.+([0-9])) ]]; then
  172.     ip=$NNTPSERVER
  173. else
  174.     dig +pfset=0x2020 "$NNTPSERVER" | while read name t ip; do
  175.     # Ignore CNAMEs and such.  dig will automatically look up the A
  176.     # record for the name the CNAME points to.
  177.     [ "$t" = A ] && break
  178.     done
  179.     if [[ "$ip" != +([0-9])+(.+([0-9])) ]]; then
  180.     print -u2 "Could not get IP address for news server $NNTPSERVER."
  181.     exit 1
  182.     fi
  183. fi
  184.  
  185. [ "$Port" = 0 ] && Port=".*"
  186.  
  187. if [ Grace -eq -1 ]; then
  188.     FindPortUsers "$ip" "$Port" > /dev/null || 
  189.     print "Noone is using the news server."
  190.     exit 0
  191. fi
  192.  
  193. Prefix="Warning: the news server"
  194.  
  195. while [ Grace -ge 0 ]; do
  196.  
  197.     case $Grace in
  198.     0) message="$Prefix is being shut down NOW!";;
  199.     1) message="$Prefix will be shut down in 1 minute.";;
  200.     *) message="$Prefix will be shut down in $Grace minutes.";;
  201.     esac
  202.     print "Sending message: $message"
  203.  
  204.     FoundUser=false
  205.     FindPortUsers "$ip" "$Port" | while read user tty; do
  206.     # Discard error output from write to avoid warnings re 
  207.     # "you have your terminal set to mesg -n"
  208.     echo "\r$message\r" | write $user $tty 2>/dev/null
  209.     FoundUser=true
  210.     done
  211.  
  212.     $FoundUser || print "No users are using the news server."
  213.  
  214.     let Grace-=1
  215.     if [ Grace -gt 0 ]; then
  216.     echo "****"
  217.     sleep 60
  218.     fi
  219. done
  220.